import axios from 'axios';
import type { AxiosResponse, AxiosRequestConfig, AxiosAdapter } from 'axios';
import { Message, Modal } from '@arco-design/web-vue';
import { getToken } from '@/utils/auth';
import { murmurHash3 } from '@/utils/index';
import { useUserStore } from '@/store';

// 添加一个标识，避免多次处理
const MOCK_PROCESSED = Symbol('MOCK_PROCESSED');

declare module 'axios' {
  export interface AxiosRequestConfig {
    needToken?: boolean; // 是否需要 token
    useMock?: boolean; // 是否使用Mock数据
    originUrl?: string; // 原始URL
    mockProcessed?: symbol; // 标记请求已被mock处理
  }
  export interface AxiosInstance {
    request<T = any>(config: AxiosRequestConfig): Promise<T>;
    get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>;
    delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>;
    head<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>;
    post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
    put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
    patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
  }
}
// 后端返回的统一格式
export interface ResultBean<T> {
  code: number;
  message: string;
  data: T;
}
/**
 * 与后端约定的接口返回格式
 */
interface ApiResponse<T = any> {
  code: number;
  message: string;
  data: T;
}

/**
 * 缓存结果
 */
const cache = new Map<string, Promise<AxiosResponse>>();
const generateKey = (config: AxiosRequestConfig) => {
  const { method, url, params, data } = config;
  const key = `${method}:${url}?${JSON.stringify(params)}${JSON.stringify(data)}`;
  return murmurHash3(key);
};

/**
 * 自定义适配器-此处主要是处理重复请求
 */
const customAdapter: AxiosAdapter = config => {
  // 如果请求标记为使用mock数据，直接返回mock数据
  if (config.useMock && !config.mockProcessed) {
    config.mockProcessed = MOCK_PROCESSED;

    console.log(`[Mock] 使用mock数据: ${config.url || config.originUrl}`);
    const url = config.originUrl || config.url || '';

    // 返回预定义的mock数据
    const mockResponse = createMockResponse(url, config);

    return Promise.resolve(mockResponse);
  }

  // 正常的请求处理
  const cacheKey = generateKey(config);
  if (cache.has(cacheKey)) {
    return cache.get(cacheKey)!;
  }

  const request = axios
    .getAdapter(axios.defaults.adapter)(config)
    .then(response => {
      cache.set(cacheKey, Promise.resolve(response));
      // 自动清理-3秒
      setTimeout(() => cache.delete(cacheKey), 3000);
      return response;
    })
    .catch(error => {
      // 失败时，立刻清理缓存
      cache.delete(cacheKey);
      throw error;
    });

  cache.set(cacheKey, request);
  return request;
};

// 创建mock响应
function createMockResponse(url: string, config: AxiosRequestConfig): AxiosResponse {
  // 默认mock数据
  let mockData = {
    code: 0,
    data: {},
    message: 'Mock数据'
  };

  // 特定接口的mock数据
  if (url.includes('/api/user/menu')) {
    mockData = {
      code: 0,
      message: '获取菜单成功',
      data: [
        {
          path: '/dashboard',
          name: 'dashboard',
          component: 'default',
          meta: {
            locale: '仪表盘',
            requiresAuth: true,
            icon: 'icon-dashboard',
            order: 0,
            roles: ['*']
          },
          children: [
            {
              path: '',
              name: 'Workplace',
              component: 'dashboard/workplace/index',
              meta: {
                locale: '工作台',
                requiresAuth: true,
                roles: ['*']
              }
            }
          ]
        },
        {
          path: '/manager',
          name: 'manager',
          component: 'default',
          meta: {
            locale: '督察管理',
            requiresAuth: true,
            icon: 'icon-list',
            order: 2,
            roles: ['*']
          },
          children: [
            {
              path: '/notice/daily',
              name: 'noticeDaily',
              component: 'manager/dailyNotice',
              meta: {
                locale: '日常通知管理',
                requiresAuth: true,
                roles: ['*']
              }
            },
            {
              path: '/notice/limited-task',
              name: 'timeLimitedTask',
              component: 'manager/timeLimitedTask',
              meta: {
                locale: '限时任务',
                requiresAuth: true,
                roles: ['*']
              }
            },
            {
              path: '/notice/self-check',
              name: 'NoticeSelfCheck',
              component: 'manager/dailyNotice',
              meta: {
                locale: '自查管理',
                requiresAuth: true,
                roles: ['*']
              }
            }
          ]
        }
      ]
    };
  } else if (url.includes('/api/funcList')) {
    console.log('[Mock] 返回funcList mock数据');
    mockData = {
      code: 200,
      message: 'success',
      data: {
        roleIds: 1,
        userName: 'admin',
        userId: 1,
        level: null,
        groupIds: 1,
        funcList: [
          {
            funcId: 'f010',
            funcName: '督察管理',
            funcPath: null,
            upFuncId: null,
            index: null,
            children: [
              {
                funcId: 'f011',
                funcName: '督察任务管理',
                funcPath: '/manager',
                upFuncId: 'f010',
                index: 1,
                children: []
              }
            ]
          },
          {
            funcId: 'f001',
            funcName: '系统管理',
            funcPath: '',
            upFuncId: null,
            index: null,
            children: [
              {
                funcId: 'f002',
                funcName: '用户管理',
                funcPath: '/user/query',
                upFuncId: 'f001',
                index: 1,
                children: []
              },
              {
                funcId: 'f003',
                funcName: '角色管理',
                funcPath: '/role/query',
                upFuncId: 'f001',
                index: 2,
                children: []
              },
              {
                funcId: 'f004',
                funcName: '组织架构管理',
                funcPath: '/group/query',
                upFuncId: 'f001',
                index: 3,
                children: []
              }
            ]
          }
        ]
      }
    };
  }

  // 模拟axios的响应格式
  return {
    data: mockData,
    status: 200,
    statusText: 'OK',
    headers: {},
    config: config
  } as AxiosResponse;
}

/**
 * 处理错误
 */
const handleError = (response: any) => {
  const code = response?.data?.code || response?.status;
  const message =
    response?.data?.message ||
    response?.statusText ||
    (typeof response === 'string' ? response : '') ||
    '网络错误，请稍后重试';

  if (code === 401) {
    Modal.error({
      title: '登录信息已过期',
      content: '登录信息已过期，请重新登录',
      okText: '重新登录',
      maskClosable: false,
      escToClose: false,
      async onOk() {
        const { logout } = useUserStore();
        await logout();
        window.location.reload();
      }
    });
  }

  Message.error({
    id: 'apiTips',
    content: message,
    duration: 3000
  });

  // 这里要保证返回的不是 undefined
  return Promise.reject(response?.data || response || { message });
};

const http = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL,
  timeout: 10000,
  withCredentials: false,
  adapter: customAdapter
});

http.interceptors.request.use(
  config => {
    // 检查是否是登录相关请求，如果是则不添加token
    const isLoginRequest =
      config.url?.includes('/login') ||
      config.url?.includes('/api/login') ||
      config.url?.includes('/api/user/login') ||
      config.url?.includes('/api/login/captcha');

    // 如果不是登录请求，则添加token
    if (!isLoginRequest) {
      const token = getToken();
      if (token) {
        // 添加token到header中
        config.headers['X-SFJ-TOKEN'] = token;
        config.headers.Authorization = `Bearer ${token}`;
        config.headers['Content-Type'] = 'application/json';
      }
    }

    return config;
  },
  error => Promise.reject(error)
);

http.interceptors.response.use(
  (response: AxiosResponse<ApiResponse>) => {
    const { code, message, data } = response.data;
    if (code === 0 || code === 200) {
      return { code, message, data }; // 返回完整的响应结构
    }
    return handleError(response);
  },
  error => handleError(error.response)
);

export const get = <T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig) =>
  http.get<T>(url, { params: data, ...config, originUrl: url });

export const post = <T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig) =>
  http.post<T>(url, data, { ...config, originUrl: url });

export const put = <T = unknown>(url: string, data?: object, config?: AxiosRequestConfig) =>
  http.put<T>(url, data, { ...config, originUrl: url });

export const del = <T = unknown>(url: string, config?: AxiosRequestConfig) =>
  http.delete<T>(url, { ...config, originUrl: url });
